---
type: tutorial
title: 添加「关于你」的动态内容
description: |-
  教程：搭建你的 Astro 博客 -
  在你的 Astro 页面上使用变量和条件渲染
---
import Checklist from '~/components/Checklist.astro';
import Spoiler from '~/components/Spoiler.astro';
import Blanks from '~/components/tutorial/Blanks.astro';
import Box from '~/components/tutorial/Box.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

现在你有了一个带有 HTML 内容的多页面网站，是时候来添加一些动态的 HTML 了！

<PreCheck>
  - 在 frontmatter 中定义你的页面标题，并在你的 HTML 中使用它
  - 条件渲染 HTML 元素
  - 添加一些关于你的内容
</PreCheck>

任何 HTML 文件都是有效的 Astro 语言。但是，你可以用 Astro 做更多的事情，而不仅仅是普通的 HTML!

## 定义和使用变量

打开 `about.astro`，它应该看起来像这样：

```astro title="src/pages/about.astro"
---

---
<html lang="zh">
  <head>
    <meta charset ="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Astro</title>
  </head>
  <body>
    <a href="/">首页</a>
    <a href="/about/">关于</a>
    <a href="/blog/">博客</a>
    <h1>关于我</h1>
    <h2>……和我的新 Astro 网站！</h2>

    <p>我正在学习 Astro 的入门教程。这是我网站上的第二个页面，也是我自己建立的第一页面！</p>

    <p>随着我完成更多教程，该站点将更新，所以请继续查看我的旅程将如何进行吧！</p>
  </body>
</html>
```

<Steps>
1. 在 frontmatter 中的代码栅栏之间添加以下一行 JavaScript：

    ```astro title="src/pages/about.astro" ins={2}
    ---
    const pageTitle = "关于我";
    ---
    ```

2. 用动态变量 `{pageTitle}` 替换 HTML 中静态的“Astro”标题和“关于我”标题。

    ```astro title="src/pages/about.astro" del={5,12} ins={6,13}
    <html lang="zh">
      <head>
        <meta charset ="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Astro</title>
        <title>{pageTitle}</title>
      </head>
      <body>
        <a href="/">首页</a>
        <a href="/about/">关于</a>
        <a href="/blog/">博客</a>
        <h1>关于我</h1>
        <h1>{pageTitle}</h1>
        <h2>……和我的新 Astro 网站！</h2>

        <p>我正在学习 Astro 的入门教程。这是我网站上的第二个页面，也是我自己建立的第一页面！</p>

        <p>随着我完成更多教程，该站点将更新，所以请继续查看我的旅程将如何进行吧！</p>
      </body>
    </html>
    ```

3. 刷新你的 `/about` 页面的实时预览。
  
    你的页面文本应该看起来是一样的，而你在浏览器标签中显示的页面标题现在应该是“关于我”，而不是“Astro”。

    你只是在你的 `.astro` 文件的两个部分分别定义然后使用了一个**变量**，而不是直接在 HTML 标签中输入文本。

4. 使用同样的模式在 `index.astro`（主页）和 `blog.astro`（我的 Astro 学习博客）创建一个 `pageTitle` 变量。在这两个地方更新这些页面的 HTML，使你的页面标题与每个页面上显示的标题一致。
</Steps>

:::note[要点]
1. 在你的 Astro 脚本中使用 JavaScript 或 TypeScript 表达式**定义变量**。
2. 在你的 Astro 模板中**使用**这些大括号内的变量来告诉 Astro 你正在使用一些 JavaScript。
:::

## 在 Astro 中编写 JavaScript 表达式

<Steps>
1. 把下面的 JavaScript 添加到你的 frontmatter 的**代码栅栏**之间：

      (你可以为自己写一些代码，但本教程将使用以下例子)。

    ```astro title="src/pages/about.astro" ins={4-9, 11}
    ---
    const pageTitle = "关于我";

    const identity = {
      firstName: "莎拉",
      country: "加拿大",
      occupation: "技术撰稿人",
      hobbies: ["摄影", "观鸟", "棒球"],
    };

    const skills = ["HTML", "CSS", "JavaScript", "React", "Astro", "Writing Docs"];
    ---
    ```

2. 然后，在你的 HTML 模板现有的内容下面添加以下代码：

    ```astro title="src/pages/about.astro"
    <p>以下是关于我的几个事实：</p>
    <ul>
      <li>我的名字是{identity.firstName}.</li>
      <li>我住在{identity.country}。我的职业是{identity.occupation}。</li>
      {identity.hobbies.length >= 2 && 
        <li>我的两个习惯：{identity.hobbies[0]}和{identity.hobbies[1]}</li>
      } 
    </ul>
    <p>我的技能是：</p>
    <ul>
      {skills.map((skill) => <li>{skill}</li>)}
    </ul>
    ```
</Steps>

:::note[要点]
1. 编写 Astro 模板非常像编写 HTML，但你可以在其中加入 JavaScript 表达式。
2. Astro 的 frontmatter 脚本只包含 JavaScript。
3. 你可以在你的 .astro 文件的任何部分使用所有现代的 JavaScript 逻辑运算符、表达式和函数。但是，大括号仅在 HTML 模板主体中是必要的。
:::

<Box icon="question-mark">

### 小测试

1. `.astro` 文件的 frontmatter 是以下列方式书写的：

    <MultipleChoice>
        <Option>HTML</Option>
        <Option>YAML</Option>
        <Option isCorrect>JavaScript</Option>
    </MultipleChoice>

2. 除了 HTML 之外，Astro 语法还允许你写：

    <MultipleChoice>
        <Option isCorrect>JavaScript 的逻辑运算符、表达式和函数</Option>
        <Option>YAML</Option>
        <Option>Markdown</Option>
    </MultipleChoice>

3. 什么时候你需要把 JavaScript 写在大括号里？
    <MultipleChoice>
        <Option>
          当你不确定它是否正确的时候。
        </Option>
        <Option isCorrect>
          当在一个 Astro 组件的 HTML 模板部分。
          </Option>
        <Option>
          在一个 Astro 组件的代码栅栏之间。
        </Option>
    </MultipleChoice>
</Box>

## 条件渲染元素

你也可以使用脚本变量来选择是否渲染你的 HTML `<body>`内容中的个别元素。

<Steps>
1. 在你的 frontmatter 脚本中添加以下几行来定义变量：

    ```astro title="src/pages/about.astro" ins={13-15}
    ---
    const pageTitle = "关于我";

    const identity = {
      firstName: "莎拉",
      country: "加拿大",
      occupation: "技术撰稿人",
      hobbies: ["摄影", "观鸟", "棒球"],
    };

    const skills = ["HTML", "CSS", "JavaScript", "React", "Astro", "Writing Docs"];

    const happy = true;
    const finished = false;
    const goal = 3;
    ---
    ```

2. 在你现有的段落下面添加以下几行。

    然后，在你的浏览器标签中检查实时预览，看看页面上显示的内容：

    ```astro title="src/pages/about.astro" /:|&&/ "?"
    {happy && <p>我非常乐意学习 Astro！</p>}

    {finished && <p>我完成了这节教程！</p>}

    {goal === 3 ? <p>我的目标是在三天内完成。</p> : <p>我的目标不是 3 天。</p>}
    ```

3. 在进行下一步之前，将你的修改提交到 GitHub。如果你想保存你的工作进度并更新你的实时网站，请随时这样做。
</Steps>

:::tip
Astro 的模板语法类似于 JSX 语法。如果你想知道如何在你的 HTML 中使用你的脚本，那么搜索一下 JSX 中是如何做到的，这可能是一个很好的出发点！
:::

<Box icon="question-mark">

### 代码分析

以下 `.astro` 代码：

```astro title="src/pages/about.astro"
---
const operatingSystem = "Linux";
const quantity = 3;
const footwear = "靴子";
const student = false;
---
```

对于以下 Astro 模板表达式，你可以预测一下对应 HTML 在浏览器中的显示什么？点击显示正确答案！

1.  `<p>{operatingSystem}</p>`

    <p>
      <Spoiler>`<p>Linux</p>`</Spoiler>
    </p>

2.  `{student && <p>我仍然在学校。</p>}`

    <p>
      <Spoiler>没有东西被显示，因为 `student` 是 `false`</Spoiler>
    </p>

3.  `<p>我有 {quantity + 8} 双{footwear}</p>`

    <p>
      <Spoiler>`<p>我有 11 双靴子</p>`</Spoiler>
    </p>

4.  `{operatingSystem === "MacOS" ? <p>我在使用 Mac。</p> : <p>我没有使用 Mac。</p>}`

    <p>
      <Spoiler>`<p>我没有使用 Mac。</p>`</Spoiler>
    </p>
</Box>

<Box icon="check-list">

## 任务清单

<Checklist>
- [ ] 我可以在 `.astro` 文件中定义并使用变量。
- [ ] 我可以条件渲染 HTML 元素。
</Checklist>
</Box>

### 相关资源

- [Astro 中的动态表达式](/zh-cn/basics/astro-syntax/#类-jsx-表达式)
